﻿// ==========================================================
// File: Universal.WebAPI.Auth.AccountService.cs
// Created: 14.12.2014
// Created By: Tim cadenbach
// 
// Copyright (C) 2014 Tim Cadenbach
// License: Apache License 2.0
// ==========================================================
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Universal.WebAPI.Auth.Model;
using Universal.WebAPI.Auth.Response;
using Universal.WebAPI.Generic;
using Universal.WebAPI.Response;
using Universal.WebAPI.Services;
using UniversalAuth.Interfaces;

namespace Universal.WebAPI.Auth.Services
{
  public class AccountService : BaseService, IAccountService
  {
    public BaseClient baseClient { get; set; }
    public TokenResponseModel BearerToken { get; set; }
    public string AccountControllerRoot { get; set; }
    public AccountService(BaseClient client, string accountControllerRoot = "api/account/")
      : base(client)
    {                                                                        
      baseClient = client;

      // if account controller is other than default value
      if (accountControllerRoot != "api/account/")
      {
        if (accountControllerRoot.Substring(accountControllerRoot.Length - 1, 1) != "/") accountControllerRoot += "/";
        AccountControllerRoot = accountControllerRoot;
      }
    }

    /// <summary>
    ///   Get a Bearer Token for authorization of a single User
    /// </summary>
    /// <param name="user">LoginModel with Logindata</param>
    /// <returns>Success: TokenResponseModel | Failure: Null</returns>
    public async Task<TokenResponseModel> GetBearerToken(LoginModel user)
    {
      try
      {
        var dict = new Dictionary<string, string>
        {
          {"grant_type", "password"},
          {"username", user.Username},
          {"password", user.Password}
        };

        BearerToken = await Client.PostValuesAsync<TokenResponseModel>("token", dict, RequestFormat.Json);
        baseClient.Token = BearerToken.AccessToken;
        return BearerToken;
        }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    /// <summary>
    ///   Returns Info for logged in User
    /// </summary>
    /// <returns></returns>
    public async Task<UserInfoResponseModel> GetUserInfo()
    {
      try
      {
        var response = await Client.GetAsync<UserInfoResponseModel>(AccountControllerRoot + "userinfo",new AuthenticationHeaderValue("Bearer", BearerToken.AccessToken));
        return (UserInfoResponseModel)response.ContentObj;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    /// <summary>
    /// Registers the user with the given Data
    /// </summary>
    /// <param name="data">Registration Data</param>
    /// <returns>Statuscode</returns>
    public async Task<ServiceResponse<RegistrationModel>> RegisterUser(RegistrationModel data)
    {
      var response = await Client.PostAsync<RegistrationModel>(AccountControllerRoot + "register", data, RequestFormat.Json);
      return response;
    }
   
    /// <summary>
    /// Sets a new Password for the user
    /// </summary>
    /// <param name="data">Registration Data</param>
    /// <returns>Statuscode</returns>
    public async Task<HttpStatusCode> SetPassword(RegistrationModel data)
    {
      var response = await Client.PostAsync<RegistrationModel>(AccountControllerRoot + "register", data, RequestFormat.Json);
      return response.StatusCode;
    }
  
    /// <summary>
    /// Logs out the current user
    /// </summary>
    /// <returns></returns>
    public async Task<HttpStatusCode> LogOut()
    {
      var response = await Client.PostAsync<RegistrationModel>(AccountControllerRoot + "logout", null, RequestFormat.Json);
      if (response.StatusCode == HttpStatusCode.OK) return response.StatusCode;
      throw new Exception("Error on Request", response.Error);
    }

    /// <summary>
    /// Returns information about the current user
    /// </summary>
    /// <param name="returnUrl">returnUrl</param>
    /// <param name="generateState">Include Generated Information</param>
    /// <returns></returns>
    public async Task<ManageInfoResponse> GetManageInfo(string returnUrl, bool generateState = false)
    {
      var response = await Client.GetAsync<ManageInfoResponse>(AccountControllerRoot + "ManageInfo?returnUrl=" + returnUrl + "&generateState=" + 
        generateState,new AuthenticationHeaderValue("Bearer", BearerToken.AccessToken));

      if(response.StatusCode == HttpStatusCode.OK) return (ManageInfoResponse) response.ContentObj;
      throw new Exception("Error on Request", response.Error);
    }


  }
}
